import jquery from 'jquery'
import md5 from 'md5'
import {an} from "vitest/dist/types-b7007192";
import {sendMessage} from 'webext-bridge/content-script'
import {collectionData} from "~/logic";
import {cache} from "~/utils/Cache";
import {getCookie} from '~/utils/cookie'

export class TRequest {
    static appKey = 12574478

    private static async token(url: string | null = null) {
        return new Promise((resolve, reject) => {
            if (url) {
                sendMessage('get-cookie', {
                    name: '_m_h5_tk',
                    url,
                }).then((res) => {
                    // const token = res.split('_')[0]
                    resolve(res?.split('_')[0])
                })
            } else {
                // console.log(getCookie('_m_h5_tk').split('_')[0])
                resolve(getCookie('_m_h5_tk').split('_')[0])
            }
        })
    }

    static getQueryParams(url: string) {
        url = url.split('?')[1]
        const params: any = {}
        const regex = /&*([^=#]+)=([^&#]*)/g
        let match
        // eslint-disable-next-line no-cond-assign
        while (match = regex.exec(url)) {
            params[match[1]] = decodeURIComponent(match[2].replace(/\+/g, ' '))
        }

        return params
    }

    static async request(api: string, params: Object, v: string, jsv: string, data: Object, appKey: any = null, jsonp: boolean = false, forceTao: Boolean = false, cacheTime: Number = 60 * 60 * 24,dataType: string = 'json',isCallback = false): Promise<any> {
        appKey = appKey || this.appKey;
        let cacheKey = {
            api: api,
            params: params,
            v: v,
            jsv: jsv,
            data: data,
            appKey: appKey,
        };
        let d: any = null;
        if (cacheTime > 0) {
            d = await cache.get(cacheKey);
        }
        if (d) {
            console.log(d, '有缓存');
            return Promise.resolve(d);
        } else {
            let apiUrl = ''
            if (location.href.indexOf('taobao.com') > -1 || forceTao) {
                apiUrl = `https://h5api.m.taobao.com/h5/${api}/${v}/`
            } else {
                apiUrl = `https://h5api.m.tmall.com/h5/${api}/${v}/`
            }
            const t = (new Date()).getTime()
            data = JSON.stringify(data)
            let token = await this.token(apiUrl);
            // console.log(token);
            let sign = md5(`${token}&${t}&${appKey}&${data}`)
            let callback = null;
            if (isCallback) {
                callback = `callback${sign}`
            }
            let response: any = false;
            if (jsonp) {
                response = await this.jsonp({
                    url: apiUrl,
                    type: 'get',
                    dataType: 'jsonp',
                    jsonp: 'callback',
                    jsonpCallback: `callback${sign}`,
                    data: {
                        appKey: appKey,
                        t: t,
                        sign: sign,
                        api: api,
                        v: v,
                        type: 'jsonp',
                        dataType: 'jsonp',
                        jsv: jsv,
                        ...params,
                        data: data,
                    },
                });
            } else {
                try{
                    response = await jquery.ajax({
                        url: apiUrl,
                        type: 'get',
                        dataType: dataType,
                        xhrFields: {
                            withCredentials: true
                        },
                        data: {
                            appKey: appKey,
                            t: t,
                            sign: sign,
                            api: api,
                            v: v,
                            jsv: jsv,
                            ...params,
                            data: data,
                            callback,
                        },
                    });
                    if (dataType == 'text') {
                      response = JSON.parse(this.extractContent(response))
                    }
                    if (typeof response.data.url != 'undefined' || (typeof response.data.data != 'undefined' && typeof response.data.data.url != 'undefined')) {
                        window.open(response.data.url || response.data.data.url);
                        return false;
                    }
                }catch(err) {
                    console.log("🚀 ~ TRequest ~ request ~ err:", err)
                    return response;
                }
            }

            if (response.ret[0] === 'SUCCESS::调用成功') {
                await cache.set(cacheKey, response.data, 60 * 60 * 24);
                return response.data
            } else if (response.ret[0] === 'FAIL_SYS_TOKEN_EXOIRED::令牌过期') {
                return this.request(api, params, v, jsv, data, appKey, jsonp, forceTao, cacheTime, dataType);
            } else {
                return false;
            }
        }

    }
    /**
     * 从字符串中提取括号内的内容 解决datatype为text返回callbackXXXX()数据方式
     * @param str - 源字符串
     * @return 括号内的内容
     */
    static extractContent(str: string) {
        let level = 0;
        let start = -1;
        let content = '';

        for (let i = 0; i < str.length; i++) {
            if (str[i] === '(') {
            if (level === 0) start = i + 1;
            level++;
            } else if (str[i] === ')') {
            level--;
            if (level === 0) {
                content = str.substring(start, i).trim();
                break;
            }
            }
        }
        return content;
    }

    static async rateList(itemId: any, pageNo: Number,): Promise<any> {
        return this.request('mtop.taobao.rate.detaillist.get', {
            ecode: 1,
            timeout: 20000,
            sessionOption: 'AutoLoginOnly',
            jsonpIncPrefix: 'haloMtop',
        }, '5.0', '2.7.0', {
            showTrueCount: false,
            auctionNumId: itemId,
            pageNo: pageNo,
            pageSize: 20,
            expression: "",
            rateType: "",
            searchImpr: "-8",
            orderType: "",
        });
    }

    static async itemShowList(itemId: any, pageNo = 1,): Promise<any> {
        let params = {};
        if (pageNo > 1) {
            let data = await this.itemShowList(itemId, pageNo - 1);
            params = data.model.buyerShow.pagination;
        }
        return this.request('mtop.taobao.ugc.itemshow.page', {
            syncCookieMode: true,
            ...(pageNo > 1 ? {} : {prefetchKey: 'pageInit',}),
            preventFallback: true,
        }, '1.0', '2.6.1', {
            itemId: itemId,
            params: JSON.stringify(params),
        }, null, true, true);
    }

    // 洋淘买家秀
    static async utcItemShowList(itemId: any, offset: number | string, pageSize: number | string = 50, isTmall = false): Promise<any> {
        const api = `https://h5api.m.${isTmall ? 'tmall' : 'taobao'}.com/h5/mtop.taobao.ugc.itemshow.list/1.0/`
        const t = (new Date()).getTime()
        const data = JSON.stringify({
            itemId,
            params: JSON.stringify({
                pagination: {
                    offset,
                    pageSize,
                },
            }),
        })
        const params = {
            appKey: this.appKey,
            t,
            preventFallback: true,
            type: 'jsonp',
            dataType: 'jsonp',
            v: '1.0',
            api: 'mtop.taobao.ugc.itemshow.list',
            jsv: '2.5.8',
            timeout: 20000,
            sign: md5(`${await this.token()}&${t}&${this.appKey}&${data}`),
            data,
            _: t,
        }
        return this.jsonp({
            url: api,
            type: 'get',
            dataType: 'jsonp',
            jsonp: 'callback',
            jsonpCallback: 'mtopjsonp1',
            data: params,
        })
    }
    /**
     * 搜索列表
     * @param q
     * @param page
     * @param sortType 1 综合排序 2 销量排序 3 销量排序 4 价格降序 4 价格升序
     * @param startPrice
     * @param endPrice
     */
    static async searchList(q: any, page: number | string = 1, sortType = 1, startPrice = null, endPrice = null): Promise<any> {
        console.log('searchList', q, page, sortType, startPrice, endPrice);
        
        return this.request('mtop.relationrecommend.WirelessRecommend.recommend', {}, '2.0', '2.6.2', {
            appId: '34385',
            params: JSON.stringify({
                isBeta: 'false',
                grayHair: 'false',
                appId: '30515',
                from: 'nt_history',
                brand: 'HUAWEI',
                info: 'wifi',
                index: '4',
                ttid: '600000@taobao_pc_10.7.0',
                needTabs: 'true',
                rainbow: '',
                areaCode: 'CN',
                vm: 'nw',
                schemaType: 'auction',
                elderHome: 'false',
                device: 'HMA-AL00',
                isEnterSrpSearch: 'true',
                countryNum: '156',
                newSearch: 'false',
                network: 'wifi',
                subtype: '',
                hasPreposeFilter: 'false',
                prepositionVersion: 'v2',
                client_os: 'Android',
                gpsEnabled: 'false',
                searchDoorFrom: 'srp',
                debug_rerankNewOpenCard: 'false',
                homePageVersion: 'v7',
                searchElderHomeOpen: 'false',
                search_action: 'initiative',
                sugg: '_4_1',
                m: 'pc',
                sversion: '13.6',
                style: 'list',
                page,
                n: 48,
                q,
                // tab: 'all',
                pageSize: 48,
                // totalPage: 100,
                // totalResults: 4800 * page,
                // sourceS: '0',
                sort: sortType === 1 || sortType === 6 ? '_coefp' : (sortType === 2 ? '_sale' : (sortType === 3 ? '_ratesum' : (sortType === 4 ? '_bid' : 'bid'))),
                // bcoffset: '',
                // ntoffset: '',
                // filterTag: '',
                // service: '',
                // prop: '',
                // loc: '',
                start_price: startPrice,
                end_price: endPrice,
                itemIds: null,
                p4pIds: null,
            }),
        },null,true,true);
        // const api = 'https://h5api.m.taobao.com/h5/mtop.relationrecommend.WirelessRecommend.recommend/2.0/'
        // const t = (new Date()).getTime()
        // const data = JSON.stringify({
        //     appId: '34385',
        //     params: JSON.stringify({
        //         isBeta: 'false',
        //         grayHair: 'false',
        //         appId: '30515',
        //         from: 'nt_history',
        //         brand: 'HUAWEI',
        //         info: 'wifi',
        //         index: '4',
        //         ttid: '600000@taobao_pc_10.7.0',
        //         needTabs: 'true',
        //         rainbow: '',
        //         areaCode: 'CN',
        //         vm: 'nw',
        //         schemaType: 'auction',
        //         elderHome: 'false',
        //         device: 'HMA-AL00',
        //         isEnterSrpSearch: 'true',
        //         countryNum: '156',
        //         newSearch: 'false',
        //         network: 'wifi',
        //         subtype: '',
        //         hasPreposeFilter: 'false',
        //         prepositionVersion: 'v2',
        //         client_os: 'Android',
        //         gpsEnabled: 'false',
        //         searchDoorFrom: 'srp',
        //         debug_rerankNewOpenCard: 'false',
        //         homePageVersion: 'v7',
        //         searchElderHomeOpen: 'false',
        //         search_action: 'initiative',
        //         sugg: '_4_1',
        //         m: 'pc',
        //         sversion: '13.6',
        //         style: 'list',
        //         page,
        //         n: 48,
        //         q,
        //         // tab: 'all',
        //         pageSize: 48,
        //         // totalPage: 100,
        //         // totalResults: 4800 * page,
        //         // sourceS: '0',
        //         sort: sortType === 1 ? '_coefp' : (sortType === 2 ? '_sale' : (sortType === 3 ? '_ratesum' : (sortType === 4 ? '_bid' : 'bid'))),
        //         // bcoffset: '',
        //         // ntoffset: '',
        //         // filterTag: '',
        //         // service: '',
        //         // prop: '',
        //         // loc: '',
        //         start_price: startPrice,
        //         end_price: endPrice,
        //         itemIds: null,
        //         p4pIds: null,
        //     }),
        // })
        // const s = md5(`${await this.token('https://s.taobao.com/search')}&${t}&${this.appKey}&${data}`)
        // const params = {
        //     appKey: this.appKey,
        //     t,
        //     jsv: '2.6.2',
        //     api: 'mtop.relationrecommend.WirelessRecommend.recommend',
        //     v: '2.0',
        //     type: 'jsonp',
        //     dataType: 'jsonp',
        //     data,
        //     sign: s,
        // }
        // return this.jsonp({
        //     url: api,
        //     type: 'get',
        //     dataType: 'jsonp',
        //     jsonp: 'callback',
        //     jsonpCallback: `callback${s}`,
        //     data: params,
        // })
    }
    static async mobileDesc(itemId: any): Promise<any> {
        const api = 'https://h5api.m.tmall.com/h5/mtop.taobao.detail.getdesc/7.0/'
        const t = (new Date()).getTime()
        const data = JSON.stringify({
            ...this.getQueryParams(location.href),
            preferWireless: 'true',
        })
        const params = {
            appKey: this.appKey,
            t,
            isSec: 0,
            ecode: 0,
            AntiFlood: true,
            AntiCreep: true,
            H5Request: true,
            type: 'jsonp',
            dataType: 'jsonp',
            jsv: '2.7.0',
            api: 'mtop.taobao.detail.getdesc',
            v: '7.0',
            timeout: 3000,
            ttid: '2019@taobao_h5_9.9.9',
            data,
            sign: md5(`${await this.token()}&${t}&${this.appKey}&${data}`),
            _: t,
        }
        return this.jsonp({
            url: api,
            type: 'get',
            dataType: 'jsonp',
            jsonp: 'callback',
            jsonpCallback: 'mtopjsonp1',
            data: params,
        })
    }
    static async cloudVideo(videoId: any): Promise<any> {
        const api = 'https://h5api.m.taobao.com/h5/mtop.taobao.cloudvideo.video.queryforh5/1.0/'
        const t = (new Date()).getTime()
        const data = JSON.stringify({
            videoId,
            from: 'detail',
        })
        const params = {
            jsv: '2.6.2',
            appKey: this.appKey,
            t,
            api: 'mtop.taobao.cloudvideo.video.queryForH5',
            v: '1.0',
            timeout: 1000,
            type: 'jsonp',
            dataType: 'jsonp',
            data,
            sign: md5(`${await this.token()}&${t}&${this.appKey}&${data}`),
            _: t,
        }
        return this.jsonp({
            url: api,
            type: 'get',
            dataType: 'jsonp',
            jsonp: 'callback',
            jsonpCallback: 'mtopjsonp1',
            data: params,
        })
    }

    static async pcTmDesc(): Promise<any> {
        const t = (new Date()).getTime()
        const data = JSON.stringify({
            ...this.getQueryParams(location.href),
            type: '1',
        })
        const params = {
            jsv: '2.7.0',
            appKey: this.appKey,
            t,
            api: 'mtop.taobao.detail.getdesc',
            v: '6.0',
            isSec: 0,
            ecode: 0,
            AntiFlood: true,
            AntiCreep: true,
            timeout: 3000,
            H5Request: true,
            type: 'jsonp',
            dataType: 'jsonp',
            data,
            sign: md5(`${await this.token()}&${t}&${this.appKey}&${data}`),
            _: t,
        }
        return this.jsonp({
            url: 'https://h5api.m.tmall.com/h5/mtop.taobao.detail.getdesc/6.0/',
            type: 'get',
            dataType: 'jsonp',
            jsonp: 'callback',
            jsonpCallback: 'mtopjsonp1',
            data: params,
        })
    }

    // 商品评论列表
    static async rateLists(itemId: any, pageNo: Number = 1, expression: string = ''): Promise<any> {
        return this.request('mtop.taobao.rate.detaillist.get', {
            timeout: 20000,
            sessionOption: 'AutoLoginOnly',
            jsonpIncPrefix: 'haloMtop',
        }, '6.0', '2.7.0', {
            showTrueCount: false,
            auctionNumId: itemId,
            rateType: "",
            searchImpr: "-8",
            expression: expression,
            orderType: "",
            pageSize: 20,
            pageNo: pageNo,
        }, null, true, true);
    }

    static async mobileDetail(itemId: any): Promise<any> {
        return this.request('mtop.taobao.detail.getdetail', {
            isSec: 0,
            ecode: 0,
            AntiFlood: true,
            AntiCreep: true,
            timeout: 3000,
            H5Request: true,
            preventFallback: true,
            ttid: '202012@taobao_h5_9.17.0',
        }, '6.0', '2.7.0', {
            itemNumId: itemId,
        }, null, true);
        // const t = (new Date()).getTime()
        // const data = JSON.stringify({
        //     itemNumId: itemId,
        // })
        // const params = {
        //     jsv: '2.7.0',
        //     appKey: this.appKey,
        //     t,
        //     api: 'mtop.taobao.detail.getdetail',
        //     v: '6.0',
        //     isSec: 0,
        //     ecode: 0,
        //     AntiFlood: true,
        //     AntiCreep: true,
        //     timeout: 3000,
        //     H5Request: true,
        //     preventFallback: true,
        //     ttid: '202012@taobao_h5_9.17.0',
        //     type: 'jsonp',
        //     dataType: 'jsonp',
        //     data,
        //     sign: md5(`${await this.token()}&${t}&${this.appKey}&${data}`),
        //     _: t,
        // }
        // return this.jsonp({
        //     url: 'https://h5api.m.taobao.com/h5/mtop.taobao.detail.getdetail/6.0/',
        //     type: 'get',
        //     dataType: 'jsonp',
        //     jsonp: 'callback',
        //     jsonpCallback: `callback${params.sign}`,
        //     data: params,
        // })
    }

    static async counter(itemId: any) {
        if (typeof collectionData[itemId] !== 'undefined') return collectionData[itemId];
        let data = await this.jsonp({
            url: 'https://count.taobao.com/counter3?keys=ICCP_1_' + itemId,
            type: 'get',
            dataType: 'jsonp',
            jsonp: 'callback',
            jsonpCallback: 'jsonp' + (new Date()).getTime() + Math.floor(Math.random() * 100000),
        });
        if (typeof data !== 'undefined' && typeof data['ICCP_1_' + itemId] !== 'undefined') {
            collectionData[itemId] = data['ICCP_1_' + itemId];
            return data['ICCP_1_' + itemId];
        } else {
            return null;
        }
    }

    static async pcTmDetail(itemId: any): Promise<any> {
        return this.request('mtop.taobao.pcdetail.data.get', {
            isSec: 0,
            ecode: 0,
            AntiFlood: true,
            AntiCreep: true,
            timeout: 10000,
            H5Request: true,
            ttid: '2022@taobao_litepc_9.20.0',
        }, '1.0', '2.6.1', {
            id: itemId,
            detail_v: '3.3.2',
            exParams: JSON.stringify({
                queryParams: `abbucket=16&id=${itemId}&ns=1&spm=a230r.1.14.31.47d972aa8RPAvp`,
                abbucket: 16,
                spm: 'a230r.1.14.31.47d972aa8RPAvp',
                id: itemId,
                ns: '1',
            }),
        });
    }

    static ugcAskTags(itemId: string): Promise<any> {
        return this.request('mtop.alibaba.ugc.ask.tags.get', {
            preventFallback: 'true',
        }, '1.0', '2.5.1', {
            targetId: itemId,
        });
    }

    static socialFeedAggregate(itemId: string): Promise<any> {
        return this.request('mtop.taobao.social.feed.aggregate', {
            preventFallback: 'true',
        }, '1.0', '2.5.1', {
            cursor: '1',
            pageId: '24501',
            env: 1,
            bizVersion: 0,
            pageNum: 1,
            pageSize: 500,
            total: 0,
            params: JSON.stringify({
                refId: itemId,
                namespace: 1,
                pageNum: 1,
                pageSize: 500,
                total: 0,
            })
        });
    }

    static async shopLike(userId: any, offset: Number = 0): Promise<any> {
        const t = (new Date()).getTime()
        const api = `https://shopsearch.taobao.com/search?user_id=${userId}&data-value=${offset}&sort=sale-desc&ajax=true&data-key=s&_=${t}`
        return this.jsonp({
            url: api,
            type: 'get',
            dataType: 'jsonp',
            jsonp: 'callback',
            jsonpCallback: `callback${t}`,
        })
    }

    static async ugcAskList(itemId: string, isTmall = false): Promise<any> {
        const api = `https://h5api.m.${isTmall ? 'tmall' : 'taobao'}.com/h5/mtop.alibaba.ugc.ask.list.get/1.0/`
        const t = (new Date()).getTime()
        const data = JSON.stringify({
            targetId: itemId,
            page: 1,
            pageSize: 10,
        })
        const sign = md5(`${this.appKey}&${t}&${this.appKey}&${data}`)
        const params = {
            preventFallback: true,
            jsv: '2.5.1',
            appKey: this.appKey,
            api: 'mtop.alibaba.ugc.ask.list.get',
            t,
            v: '1.0',
            type: 'jsonp',
            dataType: 'jsonp',
            sign,
        }
        return this.jsonp({
            url: api,
            type: 'get',
            dataType: 'jsonp',
            jsonp: 'callback',
            jsonpCallback: `callback${sign}`,
            data: params,
        })
    }

    static async itemLike(itemId: string, offset: Number = 0): Promise<any> {
        const t = (new Date()).getTime()
        const api = `https://s.taobao.com/search?ajax=true&app=i2i&sort=sale-desc&data-key=sort&data-value=${offset}&_ksTS=${t}_456&type=similar&nid=${itemId}&callback=callback${t}&_=${t}`
        return new Promise((resolve, reject) => {
            this.jsonp({
                url: api,
                type: 'get',
                dataType: 'jsonp',
                jsonp: 'callback',
                jsonpCallback: `callback${t}`,
            }).then(async (res) => {
                if (res.mods.recitem.status === 'hide') {
                    resolve(await this.itemLike(itemId, offset))
                } else {
                    resolve(res)
                }
            }).catch(async (err) => {
                reject(err)
            })
        })
    }

    static jsonp(params: any): Promise<any> {
        const dom = document.createElement('script')
        dom.id = `xcsj_${params.jsonpCallback}`
        dom.text = `function ${params.jsonpCallback}(res) { localStorage.setItem('xcsj_detail_${params.jsonpCallback}', JSON.stringify(res));}`
        document.body.append(dom)
        return new Promise((resolve, reject) => {
            params.complete = () => {
                const data = JSON.parse(localStorage.getItem(`xcsj_detail_${params.jsonpCallback}`) ?? '{}')
                if (Object.keys(data).length === 0) {
                    reject(data)
                    document.body.removeChild(dom)
                }
                if (typeof data.url != 'undefined' || (typeof data.data != 'undefined' && typeof data.data.url != 'undefined')) {
                    if (typeof data.url != 'undefined') {
                        window.open(data.url)
                    } else {
                        window.open(data.data.url)
                    }

                    reject(data)
                    try {
                        document.body.removeChild(dom)
                    } catch (e) {
                    }
                } else {
                    resolve(data)
                    localStorage.removeItem(`xcsj_detail_${params.jsonpCallback}`)
                    try {
                        document.body.removeChild(dom)
                    } catch (e) {
                    }
                }
            }
            jquery.ajax(params)
        })
    }
    /**
     * 获取商品详情页的SKU列表
     * @param id 商品ID
     * @param jsv 版本号，默认为'2.6.1'
     * @returns Promise对象，包含SKU列表数据
     */
    static async skuList(id: number, jsv: string = '2.6.1', ): Promise<any> {
        const data = {
            id: id,
            detail_v: "3.3.2",
            exParams: JSON.stringify({
                id: id
            }),
        }
        const params = {
            preventFallback:true,
            type: 'jsonp',
            dataType: 'jsonp',
            isSec: 0,
            ecode: 0,
            AntiFlood: true,
            AntiCreep: true,
            H5Request: true,
            ttid: '2022@taobao_litepc_9.17.0',
            callback: 'callback93bda743903477e7681229e860cbca1d',
        }
        return this.request('mtop.taobao.pcdetail.data.get' ,params,'1.0' , jsv, data, '',false,false, 60 * 60 * 24, 'text')
    }
     /**
     * 获取商品的下架时间
     * @param data - 包含 shopId、sellerId、itemId 的对象
     * @return Promise，成功时 resolve 店铺时间，否则 reject 错误信息
     */
    static getputawayTime(data: {shopId: string, sellerId: string,itemId: string} ): Promise<any> {
        return new Promise(async(resolve, reject) => {
            const t = (new Date()).getTime()
            const strData = JSON.stringify(data)
            const sign = md5(`${await this.token()}&${t}&${this.appKey}&${strData}`)
            const params = {
                ...data,
                token: sign
            }
            const res = await jquery.ajax({
                url: 'https://api.diantoushi.com/tao/item/putawayTime',
                type: 'get',
                dataType: 'json',
                xhrFields: {
                    withCredentials: true
                },
                data: {
                    ...params,
                },
            });
            if (res.success) {
                resolve(res)
            } else {
                console.log("🚀 ~ TRequest ~ returnnewPromise ~ err:", res)
                reject(res)
            }
        })
    }
    static async getAppsearch(id: string, page: number, jsv: string = '2.7.2', ): Promise<any> {
        const data = {
            m: "shopitemsearch",
            vm: "nw",
            style: "wf",
            sort: "first_new",
            sellerId: id,
            page: page
        }
        const params = {
            preventFallback:true,
            type: 'jsonp',
            dataType: 'jsonp',
            v: '1.0',
        }
        return this.request('mtop.taobao.wsearch.appsearch' ,params,'1.0' , jsv, data, '',false,false, 60 * 60 * 24, 'text', true)
    }
}
